package cn.tedu.net.desgin;
/*总结:
 1.延时加载的思想:是指不会再第一时间为你加载资源(创建对象)
 而是等到你需要的时候,再去帮你加载资源(创建对象)
 2.线程安全问题:多线程场景+共享数据+多条语句操作此共享数据
 解决方案:上同步锁,乐观锁降低cpu占有率.
 3.饿汉式与懒汉式的区别:
 饿汉式是不管你需不需要本类对象先帮你创建出来
 懒汉式是先不给你创建这个类的对象等到你需要的时候再帮你创建  这个就是延迟加载的思想
 */
import java.util.concurrent.locks.ReentrantReadWriteLock;

//本类用于测试单例设计模式2--懒汉式--面试重点
public class Singleton2 {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                MySingle2 single2 = MySingle2.getSingle();
                System.out.println(single2);
            }).start();
        }
    }
}

//创建自定义单例类
class MySingle2 {
    /*
     * 程序中有共享资源single,并且有多条语句操作了共享资源
     * 此时single会出现多线程数据安全隐患 --加同步锁
     *
     * */
    //为了防止外界调用此构造创建对象 进行私有化构造方法
    private MySingle2() {
        System.out.println("私有构造");
    }

    //在类部创建一个引用类型变量  延迟加载
    private static MySingle2 single;
    static ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
    //对外提供全局访问点--提供公共的方法返回类对象
    //当用户调用此方法时才说明需要本类对象了,再返回
    public static MySingle2 getSingle() {
        lock.writeLock().lock();
        try {
            //判断本方法是不是第一次调用(single有没有创建过)
            Thread.sleep(10);
            if (single == null) {//(如果是null说明之前没有创建过)
                single = new MySingle2();//(创建对象把地址值交给single保存)
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.writeLock().unlock();
        }

        //创建后返回或者直接返回
        return single;
    }
}